package com.scommunity.utils;

import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTCreator;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.exceptions.TokenExpiredException;
import com.auth0.jwt.interfaces.Claim;
import com.auth0.jwt.interfaces.DecodedJWT;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.json.JsonMapper;
import com.scommunity.domain.Emp;
import com.scommunity.domain.User;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import java.util.Base64;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

@Component
public class JWTUtils {

    @Value("${jwt.secret}")
    private String secret;

    @Value("${jwt.expire}")
    private int expire;

    @Value("${jwt.canContinue}")
    private int canContinue;

    //生成token
    public String getToken(Emp emp) {
        //现在的时间
        Date now = new Date();
        //过期的时间
        Date expireAt = new Date(now.getTime() + expire * 60 * 1000);
//        Date expireAt = new Date(now.getTime() + 10 * 1000);
        //builder的作用生成token
        JWTCreator.Builder builder = JWT.create();
        //指定token的过期时间
        builder.withExpiresAt(expireAt);
        //向token中存储数据，可以使用Base64进行解码，所以不能存储敏感数据
        builder.withClaim("id", emp.getEmpId());
        //签发token
        String token = builder.sign(Algorithm.HMAC256(secret));
        return token;
    }

    public String getToken(User user) {
        //现在的时间
        Date now = new Date();
        //过期的时间
        Date expireAt = new Date(now.getTime() + expire * 60 * 1000);
//        Date expireAt = new Date(now.getTime() + 10 * 1000);
        //builder的作用生成token
        JWTCreator.Builder builder = JWT.create();
        //指定token的过期时间
        builder.withExpiresAt(expireAt);
        //向token中存储数据，可以使用Base64进行解码，所以不能存储敏感数据
        builder.withClaim("id", user.getUserId());
        //签发token
        String token = builder.sign(Algorithm.HMAC256(secret));
        return token;
    }

    public Map<String, Long> verifyToken(String token) {
        Map<String, Long> map = new HashMap<>();
        //获取一个验证器
        JWTVerifier jwtVerifier = JWT.require(Algorithm.HMAC256(secret)).build();
        try {
            DecodedJWT verify = jwtVerifier.verify(token);
            Map<String, Claim> claimMap = verify.getClaims();
            claimMap.forEach((k, v) -> {
                map.put(k, v.asLong());
            });
            //没过期
            map.put("code", 1L);
        } catch (TokenExpiredException e) {
            //token过期
            String subToken = token.substring(token.indexOf(".") + 1, token.lastIndexOf("."));
            //Base64解码
            String json = new String(Base64.getDecoder().decode(subToken));
            //解析
            JsonMapper jsonMapper = JsonMapper.builder().build();
            try {
                Map m = jsonMapper.readValue(json, Map.class);
                //过期时间
                Long exp = Long.valueOf(m.get("exp").toString());
                Long max = exp * 1000 + canContinue * 60 * 1000;
//                Long max = exp * 1000 + 10 * 1000;
                //可以续期
                if (System.currentTimeMillis() < max) {
                    map.put("id", Long.valueOf(m.get("id").toString()));
                    map.put("code", 2L);
                    //超过最大时间，不能续期
                } else {
                    map.put("code", 3L);
                }
            } catch (JsonProcessingException ex) {
                throw new RuntimeException(ex);
            }
            //token不合法
        } catch (Exception e) {
            map.put("code", 4L);
        }
        return map;
    }

}